/********************************** (C) COPYRIGHT *********************************
* File Name          : CH456IF.H
* Author             : tech
* Version            : V1.0
* Date               : 2013/07/06
* Description        : CH456硬件接口程序
**********************************************************************************/
/*********************************************************************************
  CH456的2线接口，只需要2个I/O引脚，兼容I2C/IIC时序
 为了节约传输时间，可以适当减少SCL/SDA之间的延时
 如果希望SCL与其它电路共用，那么只要保持SDA不变化，SCL就可以用于任何用途
 如果希望SCL和SDA都与其它电路共用，那么关键是确保SDA只在SCL为低电平期间发生变化，所以SCL和SDA适合作为输出引脚使用
     1、对于SCL引脚，直接输出
     2、对于SDA引脚，输出时：
          如果SCL为低电平，那么直接输出，
          如果SCL为高电平，那么先将SCL输出低电平，再将SDA输出，最后将SCL恢复为高电平
*********************************************************************************/
#include "CH456IF.h"
uint8 CH456_DISP_BUFF[CH456_DISP_BUFFLEN];
uint8 CH456_Enable = 0;
//--------------------------------------------------
void CH456_I2c_Start( void )  // 操作起始
{
	CH456_SDA_SET;   /*发送起始条件的数据信号*/
	CH456_SDA_D_OUT;   /* 设置SDA为输出方向 */
	CH456_SCL_SET;
	CH456_SCL_D_OUT;   /* 设置SCL为输出方向 */
	DELAY;
	CH456_SDA_CLR;   /*发送起始信号*/
	DELAY;      
	CH456_SCL_CLR;   /*钳住I2C总线，准备发送或接收数据 */
}

void CH456_I2c_Stop( void )  // 操作结束
{
	CH456_SDA_CLR;
	CH456_SDA_D_OUT;   /* 设置SDA为输出方向 */
	DELAY;
	CH456_SCL_SET;
	DELAY;
	CH456_SDA_SET;  /*发送I2C总线结束信号*/
	DELAY;
	CH456_SDA_D_IN;   /* 设置SDA为输入方向 */
}

void CH456_I2c_WrByte( UINT8 dat )	//写一个字节数据
{
	UINT8 i;
	CH456_SDA_D_OUT;   /* 设置SDA为输出方向 */
	for( i = 0; i != 8; i++ )  // 输出8位数据
	{
		if( dat & 0x80 ) 
		{
		    CH456_SDA_SET;
		}
		else 
		{
		    CH456_SDA_CLR;
		}
		DELAY;
		CH456_SCL_SET;
		DELAY;  // 可选延时
		CH456_SCL_CLR;
		dat <<= 1;
	}
	CH456_SDA_D_IN;   /* 设置SDA为输入方向 */
	CH456_SDA_SET;
	DELAY;
	CH456_SCL_SET;  // 接收应答
	DELAY;
	CH456_SCL_CLR;
}

UINT8  CH456_I2c_RdByte( void )		//读一个字节数据
{
	UINT8 dat,i;
	CH456_SDA_D_IN;   /* 设置SDA为输入方向 */
//	CH456_SDA_SET;
	dat = 0;
	for( i = 0; i != 8; i++ )  // 输入8位数据
	{
		DELAY;  // 可选延时
		CH456_SCL_SET;
		DELAY;  // 可选延时
		dat <<= 1;
		if( CH456_SDA_IN ) dat++;  // 输入1位
		CH456_SCL_CLR;
	}
	CH456_SDA_SET;
	CH456_SDA_D_OUT;
	DELAY;
	CH456_SCL_SET;  // 发出无效应答
	DELAY;
	CH456_SCL_CLR;
	return dat;
}

void CH456_Write( UINT16 cmd )	//写命令
{
	CH456_I2c_Start();               //启动总线
   	CH456_I2c_WrByte( ( UINT8 )( cmd>>8 ) );
   	CH456_I2c_WrByte((UINT8)cmd);               //发送数据
  	CH456_I2c_Stop();                 //结束总线 
}

UINT8 CH456_Read( void )		//读取按键
{
	UINT8 keycode;
   	CH456_I2c_Start();                //启动总线
   	CH456_I2c_WrByte((UINT8)(CH456_GET_KEY>>8));
   	keycode=CH456_I2c_RdByte();      //读取数据
	CH456_I2c_Stop();                //结束总线
	return keycode;
}

void CH456_Display(uint8 *dataBuff,uint8 len)
{
	UINT8 Addr = (CH456_DIG0>>8);
	UINT8 index = 0;
	static uint8 cont = 0;
	if(len > CH456_DISP_BUFFLEN)
		len = CH456_DISP_BUFFLEN;
	if(CH456_Enable)
	{
		for(index = 0;index<len;index++)
		{
			CH456_Write(Addr<<8|(*dataBuff));
			Addr += 2;
			dataBuff++;
		}
		cont++;
		if(cont > 5)
		{
			cont = 0;
			CH456_Write(CH456_ONLY_DISP);
		}
	}
}

void CH456_IO_PowerDown(void)
{
    CH456_IO_Init();
	CH456_Enable = 0;
	CH456_Write(CH456_SLP_OFF);
    WaitUs(10);
    HalGpioPinInit(CH456_SCL_PIN, GPIO_OUTPUT);
    HalGpioPupdConfig(CH456_SCL_PIN,GPIO_PULL_DOWN);
    HalGpioSet(CH456_SCL_PIN,Bit_DISABLE);
    HalGpioPinInit(CH456_SDA_PIN, GPIO_OUTPUT);   
    HalGpioPupdConfig(CH456_SDA_PIN,GPIO_PULL_DOWN);   
    HalGpioSet(CH456_SDA_PIN,Bit_DISABLE);
    // HalGpioSet(CH456_POWER_PIN,Bit_ENABLE);
    HalGpioSet(CH456_POWER_PIN,Bit_DISABLE);
}

void CH456_IO_Init(void)
{
    HalGpioPinInit(CH456_POWER_PIN, GPIO_OUTPUT);
    // HalGpioSet(CH456_POWER_PIN,Bit_DISABLE);
    HalGpioSet(CH456_POWER_PIN,Bit_ENABLE);
    WaitUs(10);  
    HalGpioSet(CH456_SDA_PIN,Bit_ENABLE);
    HalGpioPinInit(CH456_SDA_PIN, GPIO_OUTPUT);
    HalGpioPupdConfig(CH456_SDA_PIN,GPIO_PULL_UP_S);
    HalGpioSet(CH456_SCL_PIN,Bit_ENABLE);
    HalGpioPinInit(CH456_SCL_PIN, GPIO_OUTPUT);   
    HalGpioPupdConfig(CH456_SCL_PIN,GPIO_PULL_UP_S);
}

void CH456_Init(void)
{
    uint8    Temp_DataBuffer[CH456_DISP_BUFFLEN];
    CH456_IO_Init();
	CH456_Enable = 1;
	WaitMs(10);
	CH456_Write(CH456_ONLY_DISP);
    WaitUs(10);
    for(uint8 i = 0; i<CH456_DISP_BUFFLEN; i++)
        Temp_DataBuffer[i] = 0;
    CH456_Display(Temp_DataBuffer,CH456_DISP_BUFFLEN);
}
